Libraries

library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──
✔ ggplot2 3.3.6     ✔ purrr   0.3.4
✔ tibble  3.1.7     ✔ dplyr   1.0.9
✔ tidyr   1.2.0     ✔ stringr 1.4.0
✔ readr   2.1.2     ✔ forcats 0.5.1
── Conflicts ───────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
library(scales)

Attaching package: ‘scales’

The following object is masked from ‘package:purrr’:

    discard

The following object is masked from ‘package:readr’:

    col_factor
library(plotly)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout
library(lubridate)

Attaching package: ‘lubridate’

The following objects are masked from ‘package:base’:

    date, intersect, setdiff, union
library(sf)
Linking to GEOS 3.10.2, GDAL 3.4.2, PROJ 8.2.1; sf_use_s2() is TRUE
library(zoo)

Attaching package: ‘zoo’

The following objects are masked from ‘package:base’:

    as.Date, as.Date.numeric

Covid Tab

#load in beds and add year column
beds <- read_csv("raw_data/non_covid_raw_data/beds_by_nhs_board_of_treatment_and_specialty.csv") %>% janitor::clean_names()

beds <- beds %>% 
mutate(quarter_date = yq(quarter),
       year = year(quarter_date), 
       .after = quarter)

beds %>% 
write_csv("clean_data/non_covid_data/beds.csv")

Plot for bed availability for all acute

# bed percentage availablity for "all acute"
# Will need to add filter for year based on user input
beds_plotly <- beds %>%
  filter(specialty_name == "All Acute") %>% 
  group_by(quarter, specialty_name) %>%
  summarise(mean_perc_occ = mean(percentage_occupancy)) %>% 
  ggplot(aes(x = quarter, y = mean_perc_occ))+
  geom_line(aes(colour = specialty_name, group = specialty_name))+
  geom_point(aes(
    text = paste0("Occupancy: ",round(mean_perc_occ, digits = 2),"%<br>","Date: ", quarter)),
    size = 0.5)+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))+
  labs(title = "Mean bed availability for all Acute Patients",
       x = "\nYear and Quarter",
       y = "Average Percentage Occupancy")

ggplotly(beds_plotly, tooltip = "text") %>% 
  config(displayModeBar = FALSE) %>% 
  layout(hoverlabel=list(bgcolor="red"))

Covid AE attendance graphs

#shows number of attendances at A&E during covid
# Title = Number of attendances at A&E 2020 - 2022
covid_ae_attendance_plotly <- covid_ae_attendance %>% 
  filter(hb_name == "All Scotland") %>% 
  ggplot() +
  geom_point(aes(x = date,
                 y = num_attendances,
                 text = paste0("Date: ", year, "-", month,
                              "<br>",
                   "Number of admissions: ", num_attendances,
                 "<br>",
                 "2017-2019 avg admissions: ", 
                 round(avg_attendances_20171819))
                 )) +
  geom_line(aes(x = date,
                y = num_attendances)) +
  geom_line(aes(x = date,
                y = avg_attendances_20171819), 
            colour = "grey60", alpha = 0.5) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
   geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4, colour = "grey50")+
  geom_vline(xintercept = as.numeric(as.Date("2021-01-01")), linetype=4, colour = "grey50")+
  geom_vline(xintercept = as.numeric(as.Date("2022-01-01")), linetype=4, colour = "grey50")+
  labs(title = "Comparison with 2018-2019 averages \n",
       x = "Date",
       y = "Number of Attendances")

covid_ae_attendance_plotly %>% 
  ggplotly(tooltip = "text") %>% 
  config(displayModeBar = FALSE) %>% 
  layout(hoverlabel = list(bgcolor = "white"))
#shows destination breakdown for A&E attendances during covid
#Title: Destination of attendances at A&E 2020 - 2022
covid_ae_destinations_plotly <- covid_ae_attendance %>% 
  filter(hb_name == "All Scotland") %>% 
  ggplot() +
  geom_point(aes(x = date,
                 y = destination_prop,
                 colour = destination,
                 text = paste0("Date: ", year, "-", month,
                               "<br>",
                               "Percentage: ", 
                              round(destination_prop*100, digits = 2), 
                              "%",
                              "<br>",
                              "2017-2019 percentage: ", 
                              round(avg_prop_20171819*100, digits = 2), 
                              "%"))) +
  geom_line(aes(x = date,
                 y = destination_prop,
                group = destination)) +
   geom_line(aes(x = date,
                 y = avg_prop_20171819,
                 colour = destination,
                group = destination), alpha = 0.5) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  scale_y_sqrt() +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
   geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4, colour = "grey50")+
  geom_vline(xintercept = as.numeric(as.Date("2021-01-01")), linetype=4, colour = "grey50")+
  geom_vline(xintercept = as.numeric(as.Date("2022-01-01")), linetype=4, colour = "grey50")+
  labs(title = "Comparison with proportion of attendances at A&E 2017 - 2019 \n",
       x = "Date",
       y = "Proportion of attendances",
       colour = "Destination")
covid_ae_destinations_plotly %>% 
  ggplotly(tooltip = "text") %>% 
  config(displayModeBar = FALSE)

Scotland Shapefile

ae_wait_times wrangling

ae_wait_times <- read_csv("raw_data/non_covid_raw_data/monthly_ae_waitingtimes_202206.csv") %>% janitor::clean_names()

#make a date and year column with the first date of every month
ae_wait_times <- ae_wait_times %>% 
  mutate(date = ym(month), .after = month,
         year = year(date))

#make a percent column with percent of patients meeting the 4hr target time
ae_wait_times <- ae_wait_times %>% 
  mutate(percent_4hr_target_achieved = (number_meeting_target_aggregate/number_of_attendances_aggregate)*100)

ae_wait_times %>% 
write_csv("clean_data/non_covid_data/ae_wait_times.csv")

add in target data for the shape files

#write in the target data for the shapefile colours
target_2007 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2007) %>% 
  rename(ae_target_2007 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2007)
  

target_2008 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>%
  filter(year == 2008) %>% 
  rename(ae_target_2008 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2008)

target_2009 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2009) %>% 
  rename(ae_target_2009 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  selecat(hbt,ae_target_2009)

target_2010 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2010) %>% 
  rename(ae_target_2010 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2010)

target_2011 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2011) %>% 
  rename(ae_target_2011 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2011)

target_2012 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2012) %>% 
  rename(ae_target_2012 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2012)

target_2013 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2013) %>% 
  rename(ae_target_2013 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2013)

target_2014 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved =
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2014) %>% 
  rename(ae_target_2014 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2014)

target_2015 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2015) %>% 
  rename(ae_target_2015 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2015)

target_2016 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2016) %>% 
  rename(ae_target_2016 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2016)

target_2017 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2017) %>% 
  rename(ae_target_2017 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2017)

target_2018 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2018) %>% 
  rename(ae_target_2018 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2018)

target_2019 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2019) %>% 
  rename(ae_target_2019 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2019)

target_2020 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2020) %>% 
  rename(ae_target_2020 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2020)

target_2021 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = 
              round(mean(percent_4hr_target_achieved, na.rm = TRUE), digits = 2)) %>% 
  filter(year == 2021) %>% 
  rename(ae_target_2021 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2021)
  

shape file wrangling

scotland <- st_read("../SG_NHS_HealthBoards_2019_shapefile/SG_NHS_HealthBoards_2019.shp")

# make a smaller version for performance issues
scotland_smaller <- scotland %>% 
  st_simplify(TRUE, dTolerance = 2000)
#fixes problems caused by above 
scotland_smaller <- sf::st_cast(scotland_smaller, "MULTIPOLYGON")

# centres <-  scotland_smaller %>% 
#   mutate(centres = st_centroid(st_make_valid(geometry))) %>%
#     mutate(lat = st_coordinates(centres)[,1],
#            long = st_coordinates(centres)[,2])a

#add in the A&E 4 hr target data for each year
scotland_smaller <-  scotland_smaller %>% 
    mutate(target_2007 = target_2007$ae_target_2007,
           target_2008 = target_2008$ae_target_2008,
           target_2009 = target_2009$ae_target_2009,
           target_2010 = target_2010$ae_target_2010,
           target_2011 = target_2011$ae_target_2011,
           target_2012 = target_2012$ae_target_2012,
           target_2013 = target_2013$ae_target_2013,
           target_2014 = target_2014$ae_target_2014,
           target_2015 = target_2015$ae_target_2015,
           target_2016 = target_2016$ae_target_2016,
           target_2017 = target_2017$ae_target_2017,
           target_2018 = target_2018$ae_target_2018,
           target_2019 = target_2019$ae_target_2019,
           target_2020 = target_2020$ae_target_2020,
           target_2021 = target_2021$ae_target_2021
                  )

# save the map
st_write(scotland_smaller, "clean_data/shapefile/scotland_smaller.gpkg", append = FALSE) 

## reload the map
scotland_smaller <- st_read("clean_data/shapefile/scotland_smaller.gpkg") 

# # This will require filtered by the year selected in the dashboard
# # Can we get the button or dropdown to pass eg "target_2016" to this in 2 places?

p <- ggplot(scotland_smaller) + 
  geom_sf(aes(fill = target_2021, 
              text = paste("<b>", HBName, "</b>\n", 
                           round(target_2021, digits = 2),"%", sep = ""))) + 
  scale_fill_viridis_c(option = "plasma", name = "4Hr A&E Target %")+
  theme_void()+
  labs(title = "Percent of A&E depts making the 4hr target")

p %>%
  ggplotly(tooltip = "text") %>%
  style(hoverlabel = list(bgcolor = "white"), hoveron = "fill")%>% 
  config(displayModeBar = FALSE)

SIMD tab

SIMD episodes line graph

simd <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_and_simd.csv") %>% janitor::clean_names()

simd <- simd %>% 
mutate(quarter_date = yq(quarter),
       year = year(quarter_date), 
       .after = quarter)

simd %>% 
write_csv("clean_data/non_covid_data/simd.csv")
# average episodes by SIMD value
# currently unfiltered for health board or admission type etc
simd_plotly <- simd %>% 
  drop_na(simd) %>%
  mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
  group_by(quarter, simd) %>% 
  summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_episodes, group = simd))+
  geom_line(aes(colour = simd))+
  geom_point(aes(text = paste0("Date: ", quarter, "<br>",
                               "Average Episodes: ", round(avg_episodes, digits = 2), "<br>",
                               "SIMD: ", simd),
                   colour = simd),size = 0.5)+
  scale_y_continuous(labels = scales::comma)+
  labs(title = "Average Hospital Episodes by SIMD Deprivation score\n",
       x = "\nYear and Quarter",
       y = "Average Episodes\n")+
  theme_minimal()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

ggplotly(simd_plotly, tooltip = "text") %>% 
  config(displayModeBar = FALSE) 

Age tab

Age episode line Graph

age_sex <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_age_and_sex.csv") %>% janitor::clean_names()

age_sex <- age_sex %>%
    mutate(quarter_date = yq(quarter),
           year = year(quarter_date),
           .after = quarter)

age_sex %>% 
  write_csv("clean_data/non_covid_data/age_sex.csv")

# Average number of episode for age groups
# currently unfiltered by department or anything else
age_plotly <- age_sex %>% 
  #filter(min_date < year & year < max_date) %>% 
  group_by(quarter, age) %>% 
  summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_episodes))+
  geom_line(aes(colour = age, group = age))+ 
  geom_point(aes(colour = age,
                 text = paste0("Date: ", quarter, "<br>",
                               "Average Episodes: ", round(avg_episodes, digits = 2), "<br>",
                               "Age Group: ", age)),size = 0.5)+
  labs(title = "Average Hospital Episodes by Age Groups\n",
       x = "\nYear and Quarter",
       y = "Average Episodes\n")+
  theme_minimal()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
  
ggplotly(age_plotly, tooltip = "text") %>% 
  config(displayModeBar = FALSE)

Age column chart

hb_agesex <- read_csv("clean_data/covid_agesex.csv")
Rows: 43516 Columns: 16
── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr  (10): month, hb, hbqf, age_group, age_group_qf, sex, sex_qf, admission_type, admission_type_qf, hb_name
dbl   (4): year, number_admissions, average20182019, percent_variation
lgl   (1): is_winter
date  (1): week_ending

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#title: Average admissions by age group 2020-2022
covid_age_plotly <- hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group != "All ages", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, age_group, is_winter) %>% 
  summarise(mean_admissions = mean(number_admissions),
            mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
  geom_col(aes(x = ordered(age_group, levels = c("Under 5",
                                                 "5 - 14",
                                                 "15 - 44",
                                                 "45 - 64",
                                                 "65 - 74",
                                                 "75 - 84",
                                                 "85 and over")),
               y = mean_admissions, 
               fill = if_else(is_winter == TRUE,
                              "Winter", "Not winter"),
               text = paste0("Age group: ", age_group,
                             "<br>",
                             "Average number of admissions: ", 
                             round(mean_admissions),
                             "<br>",
                             "2018/2019 avg admissions: ", 
                             round(mean_20182019_admissions))), 
           position = "dodge") +
  labs(title = "Comparison between winter and non-winter months",
       x = "\n Age group",
       y = "Mean number of admissions",
       fill = "Season")
`summarise()` has grouped output by 'hb_name', 'age_group'. You can override using the `.groups` argument.
Warning: Ignoring unknown aesthetics: text
covid_age_plotly %>% 
  ggplotly(tooltip = "text") %>% 
  config(displayModeBar = FALSE) 

Sex tab

Sex line graph

Scotland leaflet map


library(leaflet)
library(sf)
# scotland_smaller <-  readOGR("../SG_NHS_HealthBoards_2019_shapefile/",layer = "SG_NHS_HealthBoards_2019")
# shapeData <- spTransform(scotland_smaller, CRS("+proj=longlat +ellps=GRS80"))
# scotland <-  scotland %>% 
#   mutate(centres = st_centroid(st_make_valid(geometry))) %>%
#     mutate(lat = st_coordinates(centres)[,1],
#            long = st_coordinates(centres)[,2])
library(here)
here()
#read the geo package in
scotland = st_read("clean_data/shapefile/scotland_smaller.gpkg")

#transform so leaflet is happy with it
scotland <- st_transform(scotland, '+proj=longlat +datum=WGS84')

pal <- colorNumeric("viridis", NULL) # set colour palette

# open up leaflet and add scotland as data, along with other variables
m <- leaflet() 
m %>% addTiles() %>% 
  addPolygons(data=scotland,
              smoothFactor = 0.3, 
              fillOpacity = 1,
              fillColor = ~pal(target_2007),
              label = ~paste0( HBName,": ", target_2007),
              weight = 1, 
              highlightOptions = highlightOptions(color = "white", 
                                                            weight = 2, 
                                                            bringToFront = TRUE)) %>% 
  addLegend(pal = pal, values = scotland$target_2007, opacity = 1)

Winter tab

A&E destination breakdown

#read in clean dataset
waiting_times <- read_csv("clean_data/wait_times.csv")
#graph of A&E destination breakdown
winter_plotly <- waiting_times %>% 
  filter(discharge_destination == "Admission to Same Facility",
         !is.na(discharge_proportion)) %>% 
  group_by(date) %>% 
  summarise(mean_admission_to_same = mean(discharge_proportion)) %>% 
  ggplot() +
  geom_point(aes(x = date,
         y = mean_admission_to_same,
         text =  paste0("Date: ", date,
                               "<br>",
                               "Percentage: ", 
                              round(mean_admission_to_same*100, digits = 2), 
                              "%"))) +
  geom_line(aes(x = date,
         y = mean_admission_to_same)) +
  scale_x_date(date_breaks = "6 months", date_labels =  "%b %Y") +
    theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
  geom_vline(xintercept = as.numeric(as.Date("2008-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2009-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2010-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2011-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2012-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2013-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2014-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2015-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2016-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2017-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2018-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2019-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2021-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2022-01-01")), linetype=4, colour = "grey50", alpha = 0.7) +
  labs(title = "Proportion of attendances to selected destination \n",
       x = "\n Date",
       y = "Proportion of attendances")

winter_plotly %>% 
  ggplotly(tooltip = "text") %>% 
  config(displayModeBar = FALSE) %>% 
layout(hoverlabel = list(bgcolor = "white"))
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBMaWJyYXJpZXMKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShwbG90bHkpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHpvbykKYGBgCgoKCiMgQ292aWQgVGFiCmBgYHtyfQojbG9hZCBpbiBiZWRzIGFuZCBhZGQgeWVhciBjb2x1bW4KYmVkcyA8LSByZWFkX2NzdigicmF3X2RhdGEvbm9uX2NvdmlkX3Jhd19kYXRhL2JlZHNfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hbmRfc3BlY2lhbHR5LmNzdiIpICU+JSBqYW5pdG9yOjpjbGVhbl9uYW1lcygpCgpiZWRzIDwtIGJlZHMgJT4lIAptdXRhdGUocXVhcnRlcl9kYXRlID0geXEocXVhcnRlciksCiAgICAgICB5ZWFyID0geWVhcihxdWFydGVyX2RhdGUpLCAKICAgICAgIC5hZnRlciA9IHF1YXJ0ZXIpCgpiZWRzICU+JSAKd3JpdGVfY3N2KCJjbGVhbl9kYXRhL25vbl9jb3ZpZF9kYXRhL2JlZHMuY3N2IikKCmBgYAoKIyMgUGxvdCBmb3IgYmVkIGF2YWlsYWJpbGl0eSBmb3IgYWxsIGFjdXRlCmBgYHtyfQojIGJlZCBwZXJjZW50YWdlIGF2YWlsYWJsaXR5IGZvciAiYWxsIGFjdXRlIgojIFdpbGwgbmVlZCB0byBhZGQgZmlsdGVyIGZvciB5ZWFyIGJhc2VkIG9uIHVzZXIgaW5wdXQKYmVkc19wbG90bHkgPC0gYmVkcyAlPiUKICBmaWx0ZXIoc3BlY2lhbHR5X25hbWUgPT0gIkFsbCBBY3V0ZSIpICU+JSAKICBncm91cF9ieShxdWFydGVyLCBzcGVjaWFsdHlfbmFtZSkgJT4lCiAgc3VtbWFyaXNlKG1lYW5fcGVyY19vY2MgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBtZWFuX3BlcmNfb2NjKSkrCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBzcGVjaWFsdHlfbmFtZSwgZ3JvdXAgPSBzcGVjaWFsdHlfbmFtZSkpKwogIGdlb21fcG9pbnQoYWVzKAogICAgdGV4dCA9IHBhc3RlMCgiT2NjdXBhbmN5OiAiLHJvdW5kKG1lYW5fcGVyY19vY2MsIGRpZ2l0cyA9IDIpLCIlPGJyPiIsIkRhdGU6ICIsIHF1YXJ0ZXIpKSwKICAgIHNpemUgPSAwLjUpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpKwogIGxhYnModGl0bGUgPSAiTWVhbiBiZWQgYXZhaWxhYmlsaXR5IGZvciBhbGwgQWN1dGUgUGF0aWVudHMiLAogICAgICAgeCA9ICJcblllYXIgYW5kIFF1YXJ0ZXIiLAogICAgICAgeSA9ICJBdmVyYWdlIFBlcmNlbnRhZ2UgT2NjdXBhbmN5IikKCmdncGxvdGx5KGJlZHNfcGxvdGx5LCB0b29sdGlwID0gInRleHQiKSAlPiUgCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpICU+JSAKICBsYXlvdXQoaG92ZXJsYWJlbD1saXN0KGJnY29sb3I9InJlZCIpKQoKCmBgYAoKIyMgQ292aWQgQUUgYXR0ZW5kYW5jZSBncmFwaHMKCmBgYHtyfQojZGF0YSBmb3IgZ3JhcGhzCmNvdmlkX2FlX2F0dGVuZGFuY2UgPC0gcmVhZF9jc3YoImNsZWFuX2RhdGEvY292aWRfYWVfYXR0ZW5kYW5jZS5jc3YiKQpgYGAKCgpgYGB7cn0KI3Nob3dzIG51bWJlciBvZiBhdHRlbmRhbmNlcyBhdCBBJkUgZHVyaW5nIGNvdmlkCiMgVGl0bGUgPSBOdW1iZXIgb2YgYXR0ZW5kYW5jZXMgYXQgQSZFIDIwMjAgLSAyMDIyCmNvdmlkX2FlX2F0dGVuZGFuY2VfcGxvdGx5IDwtIGNvdmlkX2FlX2F0dGVuZGFuY2UgJT4lIAogIGZpbHRlcihoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fcG9pbnQoYWVzKHggPSBkYXRlLAogICAgICAgICAgICAgICAgIHkgPSBudW1fYXR0ZW5kYW5jZXMsCiAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlMCgiRGF0ZTogIiwgeWVhciwgIi0iLCBtb250aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj4iLAogICAgICAgICAgICAgICAgICAgIk51bWJlciBvZiBhZG1pc3Npb25zOiAiLCBudW1fYXR0ZW5kYW5jZXMsCiAgICAgICAgICAgICAgICAgIjxicj4iLAogICAgICAgICAgICAgICAgICIyMDE3LTIwMTkgYXZnIGFkbWlzc2lvbnM6ICIsIAogICAgICAgICAgICAgICAgIHJvdW5kKGF2Z19hdHRlbmRhbmNlc18yMDE3MTgxOSkpCiAgICAgICAgICAgICAgICAgKSkgKwogIGdlb21fbGluZShhZXMoeCA9IGRhdGUsCiAgICAgICAgICAgICAgICB5ID0gbnVtX2F0dGVuZGFuY2VzKSkgKwogIGdlb21fbGluZShhZXMoeCA9IGRhdGUsCiAgICAgICAgICAgICAgICB5ID0gYXZnX2F0dGVuZGFuY2VzXzIwMTcxODE5KSwgCiAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NjAiLCBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIzIG1vbnRocyIsIGRhdGVfbGFiZWxzID0gIiViICVZIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgc2l6ZSA9NykpICsKICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIikrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIxLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIikrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIyLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIikrCiAgbGFicyh0aXRsZSA9ICJDb21wYXJpc29uIHdpdGggMjAxOC0yMDE5IGF2ZXJhZ2VzIFxuIiwKICAgICAgIHggPSAiRGF0ZSIsCiAgICAgICB5ID0gIk51bWJlciBvZiBBdHRlbmRhbmNlcyIpCgpjb3ZpZF9hZV9hdHRlbmRhbmNlX3Bsb3RseSAlPiUgCiAgZ2dwbG90bHkodG9vbHRpcCA9ICJ0ZXh0IikgJT4lIAogIGNvbmZpZyhkaXNwbGF5TW9kZUJhciA9IEZBTFNFKSAlPiUgCiAgbGF5b3V0KGhvdmVybGFiZWwgPSBsaXN0KGJnY29sb3IgPSAid2hpdGUiKSkKYGBgCgoKYGBge3J9CiNzaG93cyBkZXN0aW5hdGlvbiBicmVha2Rvd24gZm9yIEEmRSBhdHRlbmRhbmNlcyBkdXJpbmcgY292aWQKI1RpdGxlOiBEZXN0aW5hdGlvbiBvZiBhdHRlbmRhbmNlcyBhdCBBJkUgMjAyMCAtIDIwMjIKY292aWRfYWVfZGVzdGluYXRpb25zX3Bsb3RseSA8LSBjb3ZpZF9hZV9hdHRlbmRhbmNlICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIAogIGdncGxvdCgpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gZGF0ZSwKICAgICAgICAgICAgICAgICB5ID0gZGVzdGluYXRpb25fcHJvcCwKICAgICAgICAgICAgICAgICBjb2xvdXIgPSBkZXN0aW5hdGlvbiwKICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUwKCJEYXRlOiAiLCB5ZWFyLCAiLSIsIG1vbnRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBlcmNlbnRhZ2U6ICIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChkZXN0aW5hdGlvbl9wcm9wKjEwMCwgZGlnaXRzID0gMiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMTctMjAxOSBwZXJjZW50YWdlOiAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQoYXZnX3Byb3BfMjAxNzE4MTkqMTAwLCBkaWdpdHMgPSAyKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlIikpKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0gZGF0ZSwKICAgICAgICAgICAgICAgICB5ID0gZGVzdGluYXRpb25fcHJvcCwKICAgICAgICAgICAgICAgIGdyb3VwID0gZGVzdGluYXRpb24pKSArCiAgIGdlb21fbGluZShhZXMoeCA9IGRhdGUsCiAgICAgICAgICAgICAgICAgeSA9IGF2Z19wcm9wXzIwMTcxODE5LAogICAgICAgICAgICAgICAgIGNvbG91ciA9IGRlc3RpbmF0aW9uLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBkZXN0aW5hdGlvbiksIGFscGhhID0gMC41KSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjMgbW9udGhzIiwgZGF0ZV9sYWJlbHMgPSAiJWIgJVkiKSArCiAgc2NhbGVfeV9zcXJ0KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgc2l6ZSA9NykpICsKICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIikrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIxLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIikrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIyLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIikrCiAgbGFicyh0aXRsZSA9ICJDb21wYXJpc29uIHdpdGggcHJvcG9ydGlvbiBvZiBhdHRlbmRhbmNlcyBhdCBBJkUgMjAxNyAtIDIwMTkgXG4iLAogICAgICAgeCA9ICJEYXRlIiwKICAgICAgIHkgPSAiUHJvcG9ydGlvbiBvZiBhdHRlbmRhbmNlcyIsCiAgICAgICBjb2xvdXIgPSAiRGVzdGluYXRpb24iKQpjb3ZpZF9hZV9kZXN0aW5hdGlvbnNfcGxvdGx5ICU+JSAKICBnZ3Bsb3RseSh0b29sdGlwID0gInRleHQiKSAlPiUgCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpCgoKYGBgCgoKCgoKCiMgU2NvdGxhbmQgU2hhcGVmaWxlCiMjIGFlX3dhaXRfdGltZXMgd3JhbmdsaW5nCmBgYHtyfQphZV93YWl0X3RpbWVzIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvbW9udGhseV9hZV93YWl0aW5ndGltZXNfMjAyMjA2LmNzdiIpICU+JSBqYW5pdG9yOjpjbGVhbl9uYW1lcygpCgojbWFrZSBhIGRhdGUgYW5kIHllYXIgY29sdW1uIHdpdGggdGhlIGZpcnN0IGRhdGUgb2YgZXZlcnkgbW9udGgKYWVfd2FpdF90aW1lcyA8LSBhZV93YWl0X3RpbWVzICU+JSAKICBtdXRhdGUoZGF0ZSA9IHltKG1vbnRoKSwgLmFmdGVyID0gbW9udGgsCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpKQoKI21ha2UgYSBwZXJjZW50IGNvbHVtbiB3aXRoIHBlcmNlbnQgb2YgcGF0aWVudHMgbWVldGluZyB0aGUgNGhyIHRhcmdldCB0aW1lCmFlX3dhaXRfdGltZXMgPC0gYWVfd2FpdF90aW1lcyAlPiUgCiAgbXV0YXRlKHBlcmNlbnRfNGhyX3RhcmdldF9hY2hpZXZlZCA9IChudW1iZXJfbWVldGluZ190YXJnZXRfYWdncmVnYXRlL251bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUpKjEwMCkKCmFlX3dhaXRfdGltZXMgJT4lIAp3cml0ZV9jc3YoImNsZWFuX2RhdGEvbm9uX2NvdmlkX2RhdGEvYWVfd2FpdF90aW1lcy5jc3YiKQpgYGAKCiMjIGFkZCBpbiB0YXJnZXQgZGF0YSBmb3IgdGhlIHNoYXBlIGZpbGVzCmBgYHtyfQojd3JpdGUgaW4gdGhlIHRhcmdldCBkYXRhIGZvciB0aGUgc2hhcGVmaWxlIGNvbG91cnMKdGFyZ2V0XzIwMDcgPC0gYWVfd2FpdF90aW1lcyAlPiUKICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSAKICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IAogICAgICAgICAgICAgIHJvdW5kKG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpLCBkaWdpdHMgPSAyKSkgJT4lIAogIGZpbHRlcih5ZWFyID09IDIwMDcpICU+JSAKICByZW5hbWUoYWVfdGFyZ2V0XzIwMDcgPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDA3KQogIAoKdGFyZ2V0XzIwMDggPC0gYWVfd2FpdF90aW1lcyAlPiUKICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSAKICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IAogICAgICAgICAgICAgIHJvdW5kKG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpLCBkaWdpdHMgPSAyKSkgJT4lCiAgZmlsdGVyKHllYXIgPT0gMjAwOCkgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAwOCA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMDgpCgp0YXJnZXRfMjAwOSA8LSBhZV93YWl0X3RpbWVzICU+JQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIAogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gCiAgICAgICAgICAgICAgcm91bmQobWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSksIGRpZ2l0cyA9IDIpKSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAwOSkgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAwOSA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjYXQoaGJ0LGFlX3RhcmdldF8yMDA5KQoKdGFyZ2V0XzIwMTAgPC0gYWVfd2FpdF90aW1lcyAlPiUKICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSAKICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IAogICAgICAgICAgICAgIHJvdW5kKG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpLCBkaWdpdHMgPSAyKSkgJT4lIAogIGZpbHRlcih5ZWFyID09IDIwMTApICU+JSAKICByZW5hbWUoYWVfdGFyZ2V0XzIwMTAgPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDEwKQoKdGFyZ2V0XzIwMTEgPC0gYWVfd2FpdF90aW1lcyAlPiUKICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSAKICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IAogICAgICAgICAgICAgIHJvdW5kKG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpLCBkaWdpdHMgPSAyKSkgJT4lIAogIGZpbHRlcih5ZWFyID09IDIwMTEpICU+JSAKICByZW5hbWUoYWVfdGFyZ2V0XzIwMTEgPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDExKQoKdGFyZ2V0XzIwMTIgPC0gYWVfd2FpdF90aW1lcyAlPiUKICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSAKICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IAogICAgICAgICAgICAgIHJvdW5kKG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpLCBkaWdpdHMgPSAyKSkgJT4lIAogIGZpbHRlcih5ZWFyID09IDIwMTIpICU+JSAKICByZW5hbWUoYWVfdGFyZ2V0XzIwMTIgPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDEyKQoKdGFyZ2V0XzIwMTMgPC0gYWVfd2FpdF90aW1lcyAlPiUKICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSAKICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IAogICAgICAgICAgICAgIHJvdW5kKG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpLCBkaWdpdHMgPSAyKSkgJT4lIAogIGZpbHRlcih5ZWFyID09IDIwMTMpICU+JSAKICByZW5hbWUoYWVfdGFyZ2V0XzIwMTMgPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDEzKQoKdGFyZ2V0XzIwMTQgPC0gYWVfd2FpdF90aW1lcyAlPiUKICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSAKICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9CiAgICAgICAgICAgICAgcm91bmQobWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSksIGRpZ2l0cyA9IDIpKSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAxNCkgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAxNCA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTQpCgp0YXJnZXRfMjAxNSA8LSBhZV93YWl0X3RpbWVzICU+JQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIAogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gCiAgICAgICAgICAgICAgcm91bmQobWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSksIGRpZ2l0cyA9IDIpKSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAxNSkgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAxNSA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTUpCgp0YXJnZXRfMjAxNiA8LSBhZV93YWl0X3RpbWVzICU+JQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIAogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gCiAgICAgICAgICAgICAgcm91bmQobWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSksIGRpZ2l0cyA9IDIpKSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAxNikgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAxNiA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTYpCgp0YXJnZXRfMjAxNyA8LSBhZV93YWl0X3RpbWVzICU+JQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIAogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gCiAgICAgICAgICAgICAgcm91bmQobWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSksIGRpZ2l0cyA9IDIpKSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAxNykgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAxNyA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTcpCgp0YXJnZXRfMjAxOCA8LSBhZV93YWl0X3RpbWVzICU+JQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIAogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gCiAgICAgICAgICAgICAgcm91bmQobWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSksIGRpZ2l0cyA9IDIpKSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAxOCkgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAxOCA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTgpCgp0YXJnZXRfMjAxOSA8LSBhZV93YWl0X3RpbWVzICU+JQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIAogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gCiAgICAgICAgICAgICAgcm91bmQobWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSksIGRpZ2l0cyA9IDIpKSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAxOSkgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAxOSA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTkpCgp0YXJnZXRfMjAyMCA8LSBhZV93YWl0X3RpbWVzICU+JQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIAogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gCiAgICAgICAgICAgICAgcm91bmQobWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSksIGRpZ2l0cyA9IDIpKSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAyMCkgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAyMCA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMjApCgp0YXJnZXRfMjAyMSA8LSBhZV93YWl0X3RpbWVzICU+JQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIAogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gCiAgICAgICAgICAgICAgcm91bmQobWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSksIGRpZ2l0cyA9IDIpKSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAyMSkgJT4lIAogIHJlbmFtZShhZV90YXJnZXRfMjAyMSA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMjEpCiAgCmBgYAoKIyMgc2hhcGUgZmlsZSB3cmFuZ2xpbmcKYGBge3J9CnNjb3RsYW5kIDwtIHN0X3JlYWQoIi4uL1NHX05IU19IZWFsdGhCb2FyZHNfMjAxOV9zaGFwZWZpbGUvU0dfTkhTX0hlYWx0aEJvYXJkc18yMDE5LnNocCIpCgojIG1ha2UgYSBzbWFsbGVyIHZlcnNpb24gZm9yIHBlcmZvcm1hbmNlIGlzc3VlcwpzY290bGFuZF9zbWFsbGVyIDwtIHNjb3RsYW5kICU+JSAKICBzdF9zaW1wbGlmeShUUlVFLCBkVG9sZXJhbmNlID0gMjAwMCkKI2ZpeGVzIHByb2JsZW1zIGNhdXNlZCBieSBhYm92ZSAKc2NvdGxhbmRfc21hbGxlciA8LSBzZjo6c3RfY2FzdChzY290bGFuZF9zbWFsbGVyLCAiTVVMVElQT0xZR09OIikKCiMgY2VudHJlcyA8LSAgc2NvdGxhbmRfc21hbGxlciAlPiUgCiMgICBtdXRhdGUoY2VudHJlcyA9IHN0X2NlbnRyb2lkKHN0X21ha2VfdmFsaWQoZ2VvbWV0cnkpKSkgJT4lCiMgICAgIG11dGF0ZShsYXQgPSBzdF9jb29yZGluYXRlcyhjZW50cmVzKVssMV0sCiMgICAgICAgICAgICBsb25nID0gc3RfY29vcmRpbmF0ZXMoY2VudHJlcylbLDJdKWEKCiNhZGQgaW4gdGhlIEEmRSA0IGhyIHRhcmdldCBkYXRhIGZvciBlYWNoIHllYXIKc2NvdGxhbmRfc21hbGxlciA8LSAgc2NvdGxhbmRfc21hbGxlciAlPiUgCiAgICBtdXRhdGUodGFyZ2V0XzIwMDcgPSB0YXJnZXRfMjAwNyRhZV90YXJnZXRfMjAwNywKICAgICAgICAgICB0YXJnZXRfMjAwOCA9IHRhcmdldF8yMDA4JGFlX3RhcmdldF8yMDA4LAogICAgICAgICAgIHRhcmdldF8yMDA5ID0gdGFyZ2V0XzIwMDkkYWVfdGFyZ2V0XzIwMDksCiAgICAgICAgICAgdGFyZ2V0XzIwMTAgPSB0YXJnZXRfMjAxMCRhZV90YXJnZXRfMjAxMCwKICAgICAgICAgICB0YXJnZXRfMjAxMSA9IHRhcmdldF8yMDExJGFlX3RhcmdldF8yMDExLAogICAgICAgICAgIHRhcmdldF8yMDEyID0gdGFyZ2V0XzIwMTIkYWVfdGFyZ2V0XzIwMTIsCiAgICAgICAgICAgdGFyZ2V0XzIwMTMgPSB0YXJnZXRfMjAxMyRhZV90YXJnZXRfMjAxMywKICAgICAgICAgICB0YXJnZXRfMjAxNCA9IHRhcmdldF8yMDE0JGFlX3RhcmdldF8yMDE0LAogICAgICAgICAgIHRhcmdldF8yMDE1ID0gdGFyZ2V0XzIwMTUkYWVfdGFyZ2V0XzIwMTUsCiAgICAgICAgICAgdGFyZ2V0XzIwMTYgPSB0YXJnZXRfMjAxNiRhZV90YXJnZXRfMjAxNiwKICAgICAgICAgICB0YXJnZXRfMjAxNyA9IHRhcmdldF8yMDE3JGFlX3RhcmdldF8yMDE3LAogICAgICAgICAgIHRhcmdldF8yMDE4ID0gdGFyZ2V0XzIwMTgkYWVfdGFyZ2V0XzIwMTgsCiAgICAgICAgICAgdGFyZ2V0XzIwMTkgPSB0YXJnZXRfMjAxOSRhZV90YXJnZXRfMjAxOSwKICAgICAgICAgICB0YXJnZXRfMjAyMCA9IHRhcmdldF8yMDIwJGFlX3RhcmdldF8yMDIwLAogICAgICAgICAgIHRhcmdldF8yMDIxID0gdGFyZ2V0XzIwMjEkYWVfdGFyZ2V0XzIwMjEKICAgICAgICAgICAgICAgICAgKQoKIyBzYXZlIHRoZSBtYXAKc3Rfd3JpdGUoc2NvdGxhbmRfc21hbGxlciwgImNsZWFuX2RhdGEvc2hhcGVmaWxlL3Njb3RsYW5kX3NtYWxsZXIuZ3BrZyIsIGFwcGVuZCA9IEZBTFNFKSAKCiMjIHJlbG9hZCB0aGUgbWFwCnNjb3RsYW5kX3NtYWxsZXIgPC0gc3RfcmVhZCgiY2xlYW5fZGF0YS9zaGFwZWZpbGUvc2NvdGxhbmRfc21hbGxlci5ncGtnIikgCgojICMgVGhpcyB3aWxsIHJlcXVpcmUgZmlsdGVyZWQgYnkgdGhlIHllYXIgc2VsZWN0ZWQgaW4gdGhlIGRhc2hib2FyZAojICMgQ2FuIHdlIGdldCB0aGUgYnV0dG9uIG9yIGRyb3Bkb3duIHRvIHBhc3MgZWcgInRhcmdldF8yMDE2IiB0byB0aGlzIGluIDIgcGxhY2VzPwoKcCA8LSBnZ3Bsb3Qoc2NvdGxhbmRfc21hbGxlcikgKyAKICBnZW9tX3NmKGFlcyhmaWxsID0gdGFyZ2V0XzIwMjEsIAogICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgiPGI+IiwgSEJOYW1lLCAiPC9iPlxuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKHRhcmdldF8yMDIxLCBkaWdpdHMgPSAyKSwiJSIsIHNlcCA9ICIiKSkpICsgCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gInBsYXNtYSIsIG5hbWUgPSAiNEhyIEEmRSBUYXJnZXQgJSIpKwogIHRoZW1lX3ZvaWQoKSsKICBsYWJzKHRpdGxlID0gIlBlcmNlbnQgb2YgQSZFIGRlcHRzIG1ha2luZyB0aGUgNGhyIHRhcmdldCIpCgpwICU+JQogIGdncGxvdGx5KHRvb2x0aXAgPSAidGV4dCIpICU+JQogIHN0eWxlKGhvdmVybGFiZWwgPSBsaXN0KGJnY29sb3IgPSAid2hpdGUiKSwgaG92ZXJvbiA9ICJmaWxsIiklPiUgCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpCmBgYAoKIyBTSU1EIHRhYgojIyBTSU1EIGVwaXNvZGVzIGxpbmUgZ3JhcGggCgpgYGB7cn0Kc2ltZCA8LSByZWFkX2NzdigicmF3X2RhdGEvbm9uX2NvdmlkX3Jhd19kYXRhL2lucGF0aWVudF9hbmRfZGF5Y2FzZV9ieV9uaHNfYm9hcmRfb2ZfdHJlYXRtZW50X2FuZF9zaW1kLmNzdiIpICU+JSBqYW5pdG9yOjpjbGVhbl9uYW1lcygpCgpzaW1kIDwtIHNpbWQgJT4lIAptdXRhdGUocXVhcnRlcl9kYXRlID0geXEocXVhcnRlciksCiAgICAgICB5ZWFyID0geWVhcihxdWFydGVyX2RhdGUpLCAKICAgICAgIC5hZnRlciA9IHF1YXJ0ZXIpCgpzaW1kICU+JSAKd3JpdGVfY3N2KCJjbGVhbl9kYXRhL25vbl9jb3ZpZF9kYXRhL3NpbWQuY3N2IikKYGBgCgpgYGB7cn0KIyBhdmVyYWdlIGVwaXNvZGVzIGJ5IFNJTUQgdmFsdWUKIyBjdXJyZW50bHkgdW5maWx0ZXJlZCBmb3IgaGVhbHRoIGJvYXJkIG9yIGFkbWlzc2lvbiB0eXBlIGV0YwpzaW1kX3Bsb3RseSA8LSBzaW1kICU+JSAKICBkcm9wX25hKHNpbWQpICU+JQogIG11dGF0ZShzaW1kID0gYXMuZmFjdG9yKHNpbWQpKSAlPiUgIyBnaXZlcyBlYWNoIHNpbWQgYSBzZXBhcmF0ZSBjb2xvdXIKICBncm91cF9ieShxdWFydGVyLCBzaW1kKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19lcGlzb2RlcyA9IG1lYW4oZXBpc29kZXMsIG5hLnJtID0gVFJVRSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2VwaXNvZGVzLCBncm91cCA9IHNpbWQpKSsKICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNpbWQpKSsKICBnZW9tX3BvaW50KGFlcyh0ZXh0ID0gcGFzdGUwKCJEYXRlOiAiLCBxdWFydGVyLCAiPGJyPiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXZlcmFnZSBFcGlzb2RlczogIiwgcm91bmQoYXZnX2VwaXNvZGVzLCBkaWdpdHMgPSAyKSwgIjxicj4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNJTUQ6ICIsIHNpbWQpLAogICAgICAgICAgICAgICAgICAgY29sb3VyID0gc2ltZCksc2l6ZSA9IDAuNSkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6Y29tbWEpKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBIb3NwaXRhbCBFcGlzb2RlcyBieSBTSU1EIERlcHJpdmF0aW9uIHNjb3JlXG4iLAogICAgICAgeCA9ICJcblllYXIgYW5kIFF1YXJ0ZXIiLAogICAgICAgeSA9ICJBdmVyYWdlIEVwaXNvZGVzXG4iKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKCmdncGxvdGx5KHNpbWRfcGxvdGx5LCB0b29sdGlwID0gInRleHQiKSAlPiUgCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpIAoKCmBgYAoKIyBBZ2UgdGFiCiMjIEFnZSBlcGlzb2RlIGxpbmUgR3JhcGgKCmBgYHtyfQphZ2Vfc2V4IDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvaW5wYXRpZW50X2FuZF9kYXljYXNlX2J5X25oc19ib2FyZF9vZl90cmVhdG1lbnRfYWdlX2FuZF9zZXguY3N2IikgJT4lIGphbml0b3I6OmNsZWFuX25hbWVzKCkKCmFnZV9zZXggPC0gYWdlX3NleCAlPiUKICAgIG11dGF0ZShxdWFydGVyX2RhdGUgPSB5cShxdWFydGVyKSwKICAgICAgICAgICB5ZWFyID0geWVhcihxdWFydGVyX2RhdGUpLAogICAgICAgICAgIC5hZnRlciA9IHF1YXJ0ZXIpCgphZ2Vfc2V4ICU+JSAKICB3cml0ZV9jc3YoImNsZWFuX2RhdGEvbm9uX2NvdmlkX2RhdGEvYWdlX3NleC5jc3YiKQpgYGAKCmBgYHtyfQoKIyBBdmVyYWdlIG51bWJlciBvZiBlcGlzb2RlIGZvciBhZ2UgZ3JvdXBzCiMgY3VycmVudGx5IHVuZmlsdGVyZWQgYnkgZGVwYXJ0bWVudCBvciBhbnl0aGluZyBlbHNlCmFnZV9wbG90bHkgPC0gYWdlX3NleCAlPiUgCiAgI2ZpbHRlcihtaW5fZGF0ZSA8IHllYXIgJiB5ZWFyIDwgbWF4X2RhdGUpICU+JSAKICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSAKICBzdW1tYXJpc2UoYXZnX2VwaXNvZGVzID0gbWVhbihlcGlzb2RlcywgbmEucm0gPSBUUlVFKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfZXBpc29kZXMpKSsKICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGFnZSwgZ3JvdXAgPSBhZ2UpKSsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gYWdlLAogICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAoIkRhdGU6ICIsIHF1YXJ0ZXIsICI8YnI+IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdmVyYWdlIEVwaXNvZGVzOiAiLCByb3VuZChhdmdfZXBpc29kZXMsIGRpZ2l0cyA9IDIpLCAiPGJyPiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWdlIEdyb3VwOiAiLCBhZ2UpKSxzaXplID0gMC41KSsKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgSG9zcGl0YWwgRXBpc29kZXMgYnkgQWdlIEdyb3Vwc1xuIiwKICAgICAgIHggPSAiXG5ZZWFyIGFuZCBRdWFydGVyIiwKICAgICAgIHkgPSAiQXZlcmFnZSBFcGlzb2Rlc1xuIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCiAgCmdncGxvdGx5KGFnZV9wbG90bHksIHRvb2x0aXAgPSAidGV4dCIpICU+JSAKICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkKYGBgCgojIyBBZ2UgY29sdW1uIGNoYXJ0CgpgYGB7cn0KaGJfYWdlc2V4IDwtIHJlYWRfY3N2KCJjbGVhbl9kYXRhL2NvdmlkX2FnZXNleC5jc3YiKQpgYGAKCgpgYGB7cn0KI3RpdGxlOiBBdmVyYWdlIGFkbWlzc2lvbnMgYnkgYWdlIGdyb3VwIDIwMjAtMjAyMgpjb3ZpZF9hZ2VfcGxvdGx5IDwtIGhiX2FnZXNleCAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiLAogICAgICAgICBhZ2VfZ3JvdXAgIT0gIkFsbCBhZ2VzIiwgCiAgICAgICAgIGhiX25hbWUgPT0gIkFsbCBTY290bGFuZCIpICU+JSAKICBncm91cF9ieShoYl9uYW1lLCBhZ2VfZ3JvdXAsIGlzX3dpbnRlcikgJT4lIAogIHN1bW1hcmlzZShtZWFuX2FkbWlzc2lvbnMgPSBtZWFuKG51bWJlcl9hZG1pc3Npb25zKSwKICAgICAgICAgICAgbWVhbl8yMDE4MjAxOV9hZG1pc3Npb25zID0gbWVhbihhdmVyYWdlMjAxODIwMTkpKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fY29sKGFlcyh4ID0gb3JkZXJlZChhZ2VfZ3JvdXAsIGxldmVscyA9IGMoIlVuZGVyIDUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjUgLSAxNCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTUgLSA0NCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNDUgLSA2NCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNjUgLSA3NCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNzUgLSA4NCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiODUgYW5kIG92ZXIiKSksCiAgICAgICAgICAgICAgIHkgPSBtZWFuX2FkbWlzc2lvbnMsIAogICAgICAgICAgICAgICBmaWxsID0gaWZfZWxzZShpc193aW50ZXIgPT0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldpbnRlciIsICJOb3Qgd2ludGVyIiksCiAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAoIkFnZSBncm91cDogIiwgYWdlX2dyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXZlcmFnZSBudW1iZXIgb2YgYWRtaXNzaW9uczogIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQobWVhbl9hZG1pc3Npb25zKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMTgvMjAxOSBhdmcgYWRtaXNzaW9uczogIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQobWVhbl8yMDE4MjAxOV9hZG1pc3Npb25zKSkpLCAKICAgICAgICAgICBwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBsYWJzKHRpdGxlID0gIkNvbXBhcmlzb24gYmV0d2VlbiB3aW50ZXIgYW5kIG5vbi13aW50ZXIgbW9udGhzIiwKICAgICAgIHggPSAiXG4gQWdlIGdyb3VwIiwKICAgICAgIHkgPSAiTWVhbiBudW1iZXIgb2YgYWRtaXNzaW9ucyIsCiAgICAgICBmaWxsID0gIlNlYXNvbiIpCgpjb3ZpZF9hZ2VfcGxvdGx5ICU+JSAKICBnZ3Bsb3RseSh0b29sdGlwID0gInRleHQiKSAlPiUgCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpIApgYGAKCgoKIyBTZXggdGFiCiMjIFNleCBsaW5lIGdyYXBoCgpgYGB7cn0Kc2V4X3Bsb3RseSA8LSBhZ2Vfc2V4ICU+JSAKICBncm91cF9ieShxdWFydGVyLCBzZXgpICU+JSAKICBzdW1tYXJpc2UoYXZnX2xlbmd0aF9vZl9lcGlzb2RlID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9lcGlzb2RlLCBuYS5ybSA9IFRSVUUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19sZW5ndGhfb2ZfZXBpc29kZSkpKwogIGdlb21fbGluZShhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCkpKwogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNleCwgCiAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlMCgiRGF0ZTogIiwgcXVhcnRlciwgIjxicj4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZW5kZXI6ICIsIHNleCkpLAogICAgICAgICAgICAgICAgIHNpemUgPSAwLjUpKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBIb3NwaXRhbCBFcGlzb2RlcyBieSBHZW5kZXJcbiIsCiAgICAgICB4ID0gIlxuWWVhciBhbmQgUXVhcnRlciIsCiAgICAgICB5ID0gIkF2ZXJhZ2UgRXBpc29kZXNcbiIpKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQogIAoKZ2dwbG90bHkoc2V4X3Bsb3RseSwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIAogIGNvbmZpZyhkaXNwbGF5TW9kZUJhciA9IEZBTFNFKQpgYGAKIyBTY290bGFuZCBsZWFmbGV0IG1hcAoKCmBgYHtyfQoKbGlicmFyeShsZWFmbGV0KQpsaWJyYXJ5KHNmKQojIHNjb3RsYW5kX3NtYWxsZXIgPC0gIHJlYWRPR1IoIi4uL1NHX05IU19IZWFsdGhCb2FyZHNfMjAxOV9zaGFwZWZpbGUvIixsYXllciA9ICJTR19OSFNfSGVhbHRoQm9hcmRzXzIwMTkiKQojIHNoYXBlRGF0YSA8LSBzcFRyYW5zZm9ybShzY290bGFuZF9zbWFsbGVyLCBDUlMoIitwcm9qPWxvbmdsYXQgK2VsbHBzPUdSUzgwIikpCiMgc2NvdGxhbmQgPC0gIHNjb3RsYW5kICU+JSAKIyAgIG11dGF0ZShjZW50cmVzID0gc3RfY2VudHJvaWQoc3RfbWFrZV92YWxpZChnZW9tZXRyeSkpKSAlPiUKIyAgICAgbXV0YXRlKGxhdCA9IHN0X2Nvb3JkaW5hdGVzKGNlbnRyZXMpWywxXSwKIyAgICAgICAgICAgIGxvbmcgPSBzdF9jb29yZGluYXRlcyhjZW50cmVzKVssMl0pCmxpYnJhcnkoaGVyZSkKaGVyZSgpCiNyZWFkIHRoZSBnZW8gcGFja2FnZSBpbgpzY290bGFuZCA9IHN0X3JlYWQoImNsZWFuX2RhdGEvc2hhcGVmaWxlL3Njb3RsYW5kX3NtYWxsZXIuZ3BrZyIpCgojdHJhbnNmb3JtIHNvIGxlYWZsZXQgaXMgaGFwcHkgd2l0aCBpdApzY290bGFuZCA8LSBzdF90cmFuc2Zvcm0oc2NvdGxhbmQsICcrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCcpCgpwYWwgPC0gY29sb3JOdW1lcmljKCJ2aXJpZGlzIiwgTlVMTCkgIyBzZXQgY29sb3VyIHBhbGV0dGUKCiMgb3BlbiB1cCBsZWFmbGV0IGFuZCBhZGQgc2NvdGxhbmQgYXMgZGF0YSwgYWxvbmcgd2l0aCBvdGhlciB2YXJpYWJsZXMKbSA8LSBsZWFmbGV0KCkgCm0gJT4lIGFkZFRpbGVzKCkgJT4lIAogIGFkZFBvbHlnb25zKGRhdGE9c2NvdGxhbmQsCiAgICAgICAgICAgICAgc21vb3RoRmFjdG9yID0gMC4zLCAKICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDEsCiAgICAgICAgICAgICAgZmlsbENvbG9yID0gfnBhbCh0YXJnZXRfMjAwNyksCiAgICAgICAgICAgICAgbGFiZWwgPSB+cGFzdGUwKCBIQk5hbWUsIjogIiwgdGFyZ2V0XzIwMDcpLAogICAgICAgICAgICAgIHdlaWdodCA9IDEsIAogICAgICAgICAgICAgIGhpZ2hsaWdodE9wdGlvbnMgPSBoaWdobGlnaHRPcHRpb25zKGNvbG9yID0gIndoaXRlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlaWdodCA9IDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmluZ1RvRnJvbnQgPSBUUlVFKSkgJT4lIAogIGFkZExlZ2VuZChwYWwgPSBwYWwsIHZhbHVlcyA9IHNjb3RsYW5kJHRhcmdldF8yMDA3LCBvcGFjaXR5ID0gMSkKYGBgCgojIFdpbnRlciB0YWIKCiMjIEEmRSBkZXN0aW5hdGlvbiBicmVha2Rvd24KCmBgYHtyfQojcmVhZCBpbiBjbGVhbiBkYXRhc2V0CndhaXRpbmdfdGltZXMgPC0gcmVhZF9jc3YoImNsZWFuX2RhdGEvd2FpdF90aW1lcy5jc3YiKQpgYGAKCmBgYHtyfQojZ3JhcGggb2YgQSZFIGRlc3RpbmF0aW9uIGJyZWFrZG93bgp3aW50ZXJfcGxvdGx5IDwtIHdhaXRpbmdfdGltZXMgJT4lIAogIGZpbHRlcihkaXNjaGFyZ2VfZGVzdGluYXRpb24gPT0gIkFkbWlzc2lvbiB0byBTYW1lIEZhY2lsaXR5IiwKICAgICAgICAgIWlzLm5hKGRpc2NoYXJnZV9wcm9wb3J0aW9uKSkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl9hZG1pc3Npb25fdG9fc2FtZSA9IG1lYW4oZGlzY2hhcmdlX3Byb3BvcnRpb24pKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fcG9pbnQoYWVzKHggPSBkYXRlLAogICAgICAgICB5ID0gbWVhbl9hZG1pc3Npb25fdG9fc2FtZSwKICAgICAgICAgdGV4dCA9ICBwYXN0ZTAoIkRhdGU6ICIsIGRhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGVyY2VudGFnZTogIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKG1lYW5fYWRtaXNzaW9uX3RvX3NhbWUqMTAwLCBkaWdpdHMgPSAyKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlIikpKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0gZGF0ZSwKICAgICAgICAgeSA9IG1lYW5fYWRtaXNzaW9uX3RvX3NhbWUpKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjYgbW9udGhzIiwgZGF0ZV9sYWJlbHMgPSAgIiViICVZIikgKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCBzaXplID03KSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAwOC0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMDktMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEwLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMS0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTItMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEzLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNC0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTUtMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE2LTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNy0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTgtMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE5LTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMC0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjEtMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIyLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpICsKICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2YgYXR0ZW5kYW5jZXMgdG8gc2VsZWN0ZWQgZGVzdGluYXRpb24gXG4iLAogICAgICAgeCA9ICJcbiBEYXRlIiwKICAgICAgIHkgPSAiUHJvcG9ydGlvbiBvZiBhdHRlbmRhbmNlcyIpCgp3aW50ZXJfcGxvdGx5ICU+JSAKICBnZ3Bsb3RseSh0b29sdGlwID0gInRleHQiKSAlPiUgCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpICU+JSAKbGF5b3V0KGhvdmVybGFiZWwgPSBsaXN0KGJnY29sb3IgPSAid2hpdGUiKSkKCmBgYAoK